from flask import Flask, request, Response, redirect
from lib.node import Node, Link
import lib.processor
import sqlite3, uuid, lib, json

app = Flask(__name__, static_folder="static", static_url_path="")
conn = sqlite3.connect("file.db", check_same_thread=False)


@app.route("/")
def serve_index():
    return redirect("index.html")


@app.route("/api/upload", methods=["POST"])
def upload():
    file = request.files["file"]
    bytes = file.read()
    file_name = file.filename
    path = str(uuid.uuid4())

    # 保存
    saveFile(path, file_name, bytes)
    return {"success": 0, "message": "", "url": "/api/preview/" + path}


def saveFile(path, file_name, bytes):
    # 保存
    cur = conn.cursor()
    cur.execute(
        "insert into file (path, file_name, data) values (?,?,?)",
        (path, file_name, bytes),
    )
    conn.commit()
    return path


@app.route("/api/download", methods=["GET"])
def preview():
    path = request.args.get("path")

    # 查询
    cur = conn.cursor()
    cur.execute("select data from file where path = ?", (path,))
    rows = cur.fetchall()
    if len(rows) == 0:
        return Response(None, status=404)
    else:
        response = Response(rows[0][0], content_type="application/octet-stream")
        return response


@app.route("/api/blueprint", methods=["POST"])
def add_blueprint():
    jso = request.get_json()
    name = jso["name"]
    data = jso["data"]

    # 保存蓝图
    cur = conn.cursor()
    cur.execute(
        "insert into blueprint (name, data) values (?, ?) ON CONFLICT(name) DO UPDATE SET data=?",
        (name, data, data),
    )
    conn.commit()
    id = cur.lastrowid

    dataj = json.loads(data)

    # 删除历史数据
    cur = conn.cursor()
    cur.execute("delete from node where name = ?", (name,))
    cur.execute("delete from link where name = ?", (name,))
    conn.commit()

    # 保存节点
    for nodem in dataj["nodes"]:
        node: Node = Node.from_dict(None, nodem)
        lib.processor.save_node(node, name)

    # 保存连接
    for link in dataj["links"]:
        if link is None:
            continue
        # [index, origin_id, origin_slot, target_id, target_slot, type]
        origin_node = lib.processor.get_node_by_name_and_id(name, link[1])
        target_node = lib.processor.get_node_by_name_and_id(name, link[3])
        lib.processor.save_link(
            name, Link(origin_node.id, link[2], target_node.id, link[4], link[5])
        )

    return {"result": 0, "data": id}


@app.route("/api/blueprint", methods=["DELETE"])
def delete_blueprint():
    name = request.args.get("name")

    # 保存
    cur = conn.cursor()
    cur.execute("delete from blueprint where name = ?", (name,))
    cur.commit()
    return {"result": 0}


@app.route("/api/blueprint", methods=["GET"])
def get_blueprint():
    # 获取请求
    name = request.args.get("name")

    # 查询
    cur = conn.cursor()
    cur.execute("select data from blueprint where name = ?", (name,))
    row = cur.fetchone()
    if row:
        return {"result": 0, "data": row[0]}
    else:
        return {"result": 1}


@app.route("/api/allWidget", methods=["GET"])
def all_widget():
    ms = lib.all()
    return [m().to_json() for m in ms]


@app.route("/api/trigger", methods=["POST"])
def trigger():
    jso = request.get_json()
    name = jso["name"]
    nodeId = jso["nodeId"]

    node = lib.processor.get_node_by_name_and_id(name, nodeId)
    if node:
        lib.processor.trigger(node.id)

    return {"result": 0}


@app.route("/api/node/detail", methods=["POST"])
def node_detail():
    jso = request.get_json()
    name = jso["name"]
    nodeId = jso["nodeId"]

    node = lib.processor.get_node_by_name_and_id(name, nodeId)

    return {"result": 0, "data": node.to_dict()}


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
